package com.dd.cloud.user.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

/**
 * mq发送消息 队列消息生产者
 *
 * @author zk
 */
@Configuration
@Slf4j
public class RabbitSend {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 设置确认回调
     * 如果消息没有到exchange,则confirm回调,ack=false
     * 如果消息到达exchange,则confirm回调,ack=true
     * exchange到queue成功,则不回调return
     * exchange到queue失败,则回调return
     */
    final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            log.info("确认回调:{}, ack:{} ", correlationData, ack);
            if (!ack) {
                log.info("异常处理....");
            }
        }

    };

    /**
     * 设置异常回调
     */
    final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
        @Override
        public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
            log.info("异常回调: " + message.toString());
        }

    };


    /**
     * 发送mq队列
     *
     * @param exchange   发送的交换机
     * @param routingKey 路由key
     * @param msg        数据
     */
    public void sendMessage(String exchange, String routingKey, Object msg) {
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(confirmCallback);
        rabbitTemplate.setReturnCallback(returnCallback);
        /**
         * 发送消息
         */
        rabbitTemplate.convertAndSend(exchange, routingKey, msg);
    }

    /**
     * 发送延时队列
     *
     * @param exchange   发送到的交互机
     * @param routingKey 路由key
     * @param msg        数据
     * @param time       延迟时间, 毫秒值
     */
    public void sendMessageDelay(String exchange, String routingKey, Object msg, Long time) {
        rabbitTemplate.convertAndSend(
                exchange,
                routingKey,
                msg,
                message -> {
                    //注意这里时间可以使long，而且是设置header
                    message.getMessageProperties().setHeader("x-delay", time);//设置延迟多少毫秒
                    return message;
                }
        );
    }
}
